Add support for MXF. From Alex Mottram <alex_m@cox-internet.com>
authorrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sat, 14 Sep 2002 14:42:38 +0000 (14:42 +0000)
committerrobertl <robertl@f51c46e8-681c-474f-0cfe-069cfd0219fb>
Sat, 14 Sep 2002 14:42:38 +0000 (14:42 +0000)
gpsbabel/mxf.c [new file with mode: 0644]
gpsbabel/reference/mxf.mxf [new file with mode: 0644]

diff --git a/gpsbabel/mxf.c b/gpsbabel/mxf.c
new file mode 100644 (file)
index 0000000..e360efe
--- /dev/null
@@ -0,0 +1,291 @@
+/*
+    Mapsend Exchange Format (.mxf)
+    (Maptech Terrain Navigator, Terrain Professional, Take a Hike)
+    (Aka Yet Another CSV Format) 
+
+    Contributed to gpsbabel by Alex Mottram
+
+    LAT,LON,"WPT Name", "Big Name","Small Name",COLORxFF,(int)ICON
+
+    as described at: www.memory-map.co.uk/downloads/PDF/mm_tsb3_import_export_text_files.pdf 
+    tested against ExpertGPS import/export .mxf files.
+
+    Copyright (C) 2002 Robert Lipe, robertlipe@usa.net
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111 USA
+
+ */
+
+#include "defs.h"
+#include <ctype.h>
+
+#define MYNAME "MXF"
+
+static FILE *file_in;
+static FILE *file_out;
+
+/* remember what dave & gamera say about pointer math... */
+static char * 
+cvsstringclean(char * string)
+{
+    static char * p1 = NULL;
+    char * p2 = NULL;
+    
+    if (! string) { 
+        return (string); /* :) */
+    }
+
+    p2 = string;
+    
+    while ((*p2) && (p2++)) { }
+    p2--;
+    
+    while (isspace(*p2)) {
+        *p2 = '\0';
+        p2--;
+    }
+    
+    p1 = string;
+    
+    while (isspace(*p1)) {
+        p1++;
+    }
+
+    /* yank quotes in pairs only if they are bounding us */
+    while ((*p1 == '"') && (*p2 == '"')) {
+        *p2 = '\0';
+        p2--;
+        p1++;
+    }
+
+    return (p1);    
+}
+
+/* string parser.  sorta like strtok with quotes & pointers.. */
+static char * 
+csvparse(char *stringstart, char *delimiter)
+{
+    char *sp;
+    static char *p = NULL;
+    static char *tmp = NULL;
+    size_t dlen;
+    int quotedepth = 0;
+
+    if (!p) {
+       p = stringstart;
+
+       if (!p) {
+           return (NULL);
+       }
+    }
+
+    if (tmp) {
+       free(tmp);
+       tmp = NULL;
+    }
+
+    sp = p;
+
+    dlen = strlen(delimiter);
+
+    while ((*p) && (! tmp)) {
+       if (*p == '"') {
+           if (quotedepth) 
+               quotedepth--;
+           else 
+               quotedepth++;
+       }
+
+       if ((!quotedepth) && (strncmp(p, delimiter, dlen) == 0)) {
+               tmp = (char *) calloc((p - sp) + 1, sizeof(char));
+               if (! tmp) {
+                   fatal(MYNAME ": cannot allocate memory\n");
+               }
+               strncpy(tmp, sp, (p - sp));
+       }
+       p++;
+    }
+
+    if (!tmp) {
+       tmp = (char *) calloc((p - sp) + 1, sizeof(char));
+
+       if (! tmp) {
+           fatal(MYNAME ": cannot allocate memory\n");
+       }
+
+       strncpy(tmp, sp, (p - sp));
+
+       p = NULL;
+    }
+
+    if (tmp) {
+       return (tmp);
+    }
+
+    return (NULL);
+}
+
+static void 
+rd_init(const char *fname)
+{
+    file_in = fopen(fname, "r");
+    if (file_in == NULL) {
+       fatal(MYNAME ": Cannot open %s for reading\n", fname);
+    }
+}
+
+static void 
+rd_deinit(void)
+{
+    fclose(file_in);
+}
+
+static void 
+wr_init(const char *fname)
+{
+    file_out = fopen(fname, "w");
+    if (file_out == NULL) {
+       fatal(MYNAME ": Cannot open %s for writing\n", fname);
+    }
+}
+
+static void 
+wr_deinit(void)
+{
+    fclose(file_out);
+}
+
+static void 
+data_read(void)
+{
+    char buff[256];
+    char *s;
+    waypoint *wpt_tmp;
+    int i;
+    int linecount = 0;
+
+    do {
+        linecount++;
+       memset(&buff, '\0', sizeof(buff));
+       fgets(buff, sizeof(buff), file_in);
+
+       if (strlen(buff)) {
+
+           wpt_tmp = calloc(sizeof(*wpt_tmp), 1);
+
+           if (wpt_tmp == NULL) {
+               fatal(MYNAME ": cannot allocate memory\n");
+           }
+
+           s = buff;
+           s = csvparse(s, ",");
+
+           i = 0;
+           while (s) {
+               switch (i) {
+               case 0:
+                   wpt_tmp->position.latitude.degrees = atof(s);
+                   break;
+               case 1:
+                   wpt_tmp->position.longitude.degrees = atof(s);
+                   break;
+               case 2:
+                   wpt_tmp->description = strdup(cvsstringclean(s));
+                   break;
+               case 3:
+                   wpt_tmp->shortname = strdup(cvsstringclean(s));
+                   break;
+               case 4:
+                    /* ignore.  another name-type  */
+                   break;
+               case 5:
+                   /* ignore: color  */
+                   break;
+               case 6:
+                   /* ignore: icon */
+                   break;
+               default:
+                   /* whoa! nelly */
+                   printf ("%s: Warning: data fields on line %d exceed specification.\n", 
+                       MYNAME, linecount);
+                   break;
+               }
+               i++;
+
+               s = csvparse(NULL, ",");
+           }
+           
+           if (i != 7) {
+               free(wpt_tmp);
+               printf ("%s: WARNING - extracted %d fields from line %d. \nData on line ignored.\n", 
+                   MYNAME, i, linecount);
+           } else {
+               waypt_add(wpt_tmp);
+           }
+
+       } else {
+            /* this complains too much 
+            * printf ("%s: WARNING - blank line at line %d.\n", MYNAME, linecount);
+             */
+       }
+
+    } while (!feof(file_in));
+}
+
+static void 
+mxf_disp(waypoint * wpt)
+{
+    double lon, lat;
+    int icon = 47; /* default to "dot" */
+    const char *color_hex = "ff0000";
+
+    lon = wpt->position.longitude.degrees;
+    lat = wpt->position.latitude.degrees;
+
+    fprintf(file_out, "%08.5f, %08.5f, \"%s\", \"%s\", \"%s\", %s, %d\n",
+           lat, lon,
+           wpt->description, wpt->shortname, wpt->description, 
+           color_hex, icon);
+
+}
+
+static void 
+data_write(void)
+{
+    waypt_disp_all(mxf_disp);
+}
+
+
+ff_vecs_t mxf_vecs = {
+    rd_init,
+    wr_init,
+    rd_deinit,
+    wr_deinit,
+    data_read,
+    data_write,
+};
+
+
+/*
+    Excerpt from Maptech help file.
+
+    Below is an example of the .MXF file format:
+
+    43.7601389, -071.2791299, "Cottonwood", "Cttnwd", "A very large tree", 800080, 137
+    43.7617236, -071.2917695, "Fencepost", "Fncpst", "", 808080, 14
+    43.7576237, -071.2888850, "Aspen", "Aspen", "", ffff, 137
+    43.7562457, -071.2777147, "Cache", "Cache", "", ff, 138
+    43.7576583, -071.2701399, "Tent site", "Tntst", "", ff, 111
+*/
diff --git a/gpsbabel/reference/mxf.mxf b/gpsbabel/reference/mxf.mxf
new file mode 100644 (file)
index 0000000..0e15ac9
--- /dev/null
@@ -0,0 +1,6 @@
+00.00000, 00.00000, "WPT Name", "Big Name", "WPT Name", ff0000, 47
+43.76014, -71.27913, "Cottonwood", "Cttnwd", "Cottonwood", ff0000, 47
+43.76172, -71.29177, "Fencepost", "Fncpst", "Fencepost", ff0000, 47
+43.75762, -71.28888, "Aspen", "Aspen", "Aspen", ff0000, 47
+43.75625, -71.27771, "Cache", "Cache", "Cache", ff0000, 47
+43.75766, -71.27014, "Tent site", "Tntst", "Tent site", ff0000, 47